package common

import (
	"fmt"
	"strconv"
	"strings"

	"gitee.com/tomatomeatman/golang-repository/bricks3/model/dbinfo"
	"gitee.com/tomatomeatman/golang-repository/bricks3/model/globalvariable"
	"gitee.com/tomatomeatman/golang-repository/bricks3/utils/ginutil"
	"gitee.com/tomatomeatman/golang-repository/bricks3/utils/sqlfactory"
	"github.com/gin-gonic/gin"
)

// var (
// 	mainDb     string
// 	mainDbOnce sync.Once //单次赋值操作
// )

type BaseSystemController struct {
}

/**
 * 初始化
 */
func init() {
	controller := &BaseSystemController{}
	globalvariable.Add("Module@BaseSystemController", controller)

	ginutil.AddUrl("/basesystem/find/table", controller.FindTable, ginutil.POST)
	ginutil.AddUrl("/basesystem/find/field", controller.FindField, ginutil.POST)
	ginutil.AddUrl("/basesystem/find/column", controller.FindFieldName, ginutil.POST)
	ginutil.AddUrl("/basesystem/find/page", controller.FindPage, ginutil.POST)
	ginutil.AddUrl("/basesystem/find/all", controller.FindAll, ginutil.POST)
	ginutil.AddUrl("/basesystem/find/key", controller.FindByKey, ginutil.POST)
	ginutil.AddUrl("/basesystem/find/key/one", controller.FindByKeyOne, ginutil.POST)
	ginutil.AddUrl("/basesystem/find/id", controller.FindById, ginutil.POST)
	ginutil.AddUrl("/basesystem/find/max", controller.FindMax, ginutil.POST)
	ginutil.AddUrl("/basesystem/find/min", controller.FindMin, ginutil.POST)
	ginutil.AddUrl("/basesystem/find/has", controller.FindHas, ginutil.POST)
	ginutil.AddUrl("/basesystem/find/count", controller.FindCount, ginutil.POST)
	ginutil.AddUrl("/basesystem/add", controller.Add, ginutil.POST)
	ginutil.AddUrl("/basesystem/edit", controller.Edit, ginutil.POST)
	ginutil.AddUrl("/basesystem/del", controller.Del, ginutil.POST)
	ginutil.AddUrl("/basesystem/find/tree", controller.FindTree, ginutil.POST)
	ginutil.AddUrl("/basesystem/find/group", controller.FindGroup, ginutil.POST)
	ginutil.AddUrl("/basesystem/clear/cache", controller.ClearCache, ginutil.POST)
}

func (c *BaseSystemController) FindTable(ctx *gin.Context) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	onlyTable := false
	if temp, ok := params["onlyTable"]; ok {
		str := fmt.Sprintf("%v", temp)
		iData, err := strconv.ParseInt(str, 10, 64)
		if err != nil {
			onlyTable = false
		}

		onlyTable = iData == 1
	}

	return sqlfactory.FindTable(GetMainDb(), onlyTable)
}

func (c *BaseSystemController) FindField(ctx *gin.Context) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	var tableName string
	if temp, ok := params["tableName"]; ok {
		tableName = strings.TrimSpace(fmt.Sprintf("%v", temp))
	}

	if tableName == "" {
		return false, "tableName参数为空", 9001
	}

	return sqlfactory.FindField(GetMainDb(), tableName)
}

func (c *BaseSystemController) FindFieldName(ctx *gin.Context) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	var tableName string
	if temp, ok := params["tableName"]; ok {
		tableName = strings.TrimSpace(fmt.Sprintf("%v", temp))
	}

	if tableName == "" {
		return false, "tableName参数为空", 9001
	}

	return sqlfactory.FindFieldName(GetMainDb(), tableName)
}

// FindById 根据ID查询
func (c *BaseSystemController) FindById(ctx *gin.Context) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	bl, msg, da := sqlfactory.AnalysisEntity(GetMainDb(), params["tableName"])
	if !bl {
		return bl, msg, da
	}

	entity := da.(*dbinfo.TableInfo)

	id, ok := params[entity.KeyName()]
	if !ok {
		return false, "没有编号参数:" + entity.KeyName(), 9204
	}

	var fields []string
	if fieldsParam, ok := params["fields"].([]string); ok {
		fields = fieldsParam
	}

	return GetService(entity.DbName, entity.Name).FindById(ctx, entity, id, fields)
}

// FindPage 分页查询
func (c *BaseSystemController) FindPage(ctx *gin.Context) (bool, string, interface{}) {
	var findByPageParam dbinfo.FindByPageParam
	ginutil.GetParamsToBind(ctx, &findByPageParam)

	bl, msg, data := sqlfactory.AnalysisEntity(GetMainDb(), findByPageParam.Extend["tableName"])
	if !bl {
		return bl, msg, data
	}

	entity := data.(*dbinfo.TableInfo)

	return GetService(entity.DbName, entity.Name).FindPage(ctx, entity, &findByPageParam)
}

// FindByAll 查询所有
func (c *BaseSystemController) FindAll(ctx *gin.Context) (bool, string, interface{}) {
	tableName := ginutil.GetParam(ctx, "tableName", "").(string)

	bl, msg, data := sqlfactory.AnalysisEntity(GetMainDb(), tableName)
	if !bl {
		return bl, msg, data
	}

	entity := data.(*dbinfo.TableInfo)

	return GetService(entity.DbName, entity.Name).FindAll(ctx, entity)
}

// FindByKey 根据条件查询多条
func (c *BaseSystemController) FindByKey(ctx *gin.Context) (bool, string, interface{}) {
	var findByPageParam dbinfo.FindByPageParam
	ginutil.GetParamsToBind(ctx, &findByPageParam)

	bl, msg, data := sqlfactory.AnalysisEntity(GetMainDb(), findByPageParam.Extend["tableName"])
	if !bl {
		return bl, msg, data
	}

	entity := data.(*dbinfo.TableInfo)

	return GetService(entity.DbName, entity.Name).FindByKey(ctx, entity, findByPageParam.Fields, findByPageParam.Conditions, findByPageParam.Orders)
}

// FindByKeyOne 根据条件查询单条
func (c *BaseSystemController) FindByKeyOne(ctx *gin.Context) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	var fields []string
	if fieldsParam, ok := params["fields"].([]interface{}); ok {
		fields = make([]string, len(fieldsParam))
		for i, v := range fieldsParam {
			fields[i] = fmt.Sprintf("%v", v)
		}
	}

	bl, msg, data := sqlfactory.AnalysisEntity(GetMainDb(), params["tableName"])
	if !bl {
		return bl, msg, data
	}

	entity := data.(*dbinfo.TableInfo)

	return GetService(entity.DbName, entity.Name).FindByKeyOne(ctx, entity, fields, params)
}

// FindMax 查询最大值
func (c *BaseSystemController) FindMax(ctx *gin.Context) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	field, ok := params["field"].(string)
	if !ok {
		return false, "从请求参数解析数据发生异常", 9001
	}

	conditions, ok := params["conditions"].(map[string]interface{})

	bl, msg, data := sqlfactory.AnalysisEntity(GetMainDb(), params["tableName"])
	if !bl {
		return bl, msg, data
	}

	entity := data.(*dbinfo.TableInfo)

	return GetService(entity.DbName, entity.Name).FindMax(ctx, entity, field, conditions)
}

// FindMin 查询最小值
func (c *BaseSystemController) FindMin(ctx *gin.Context) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	field, ok := params["field"].(string)
	if !ok {
		return false, "从请求参数解析数据发生异常", 9001
	}

	conditions, ok := params["conditions"].(map[string]interface{})

	bl, msg, data := sqlfactory.AnalysisEntity(GetMainDb(), params["tableName"])
	if !bl {
		return bl, msg, data
	}

	entity := data.(*dbinfo.TableInfo)

	return GetService(entity.DbName, entity.Name).FindMin(ctx, entity, field, conditions)
}

// FindHas 查询是否存在
func (c *BaseSystemController) FindHas(ctx *gin.Context) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	field, ok := params["field"].(string)
	if !ok {
		return false, "从请求参数解析数据发生异常", 9001
	}

	value, ok := params["value"]
	if !ok {
		return false, "从请求参数解析数据发生异常", 9001
	}

	bl, msg, data := sqlfactory.AnalysisEntity(GetMainDb(), params["tableName"])
	if !bl {
		return bl, msg, data
	}

	entity := data.(*dbinfo.TableInfo)

	return GetService(entity.DbName, entity.Name).FindHas(ctx, entity, field, value)
}

// FindCount 查询数量
func (c *BaseSystemController) FindCount(ctx *gin.Context) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	bl, msg, data := sqlfactory.AnalysisEntity(GetMainDb(), params["tableName"])
	if !bl {
		return bl, msg, data
	}

	entity := data.(*dbinfo.TableInfo)

	return GetService(entity.DbName, entity.Name).FindCount(ctx, entity, params)
}

// AddData 添加数据
func (c *BaseSystemController) Add(ctx *gin.Context) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	bl, msg, da := sqlfactory.AnalysisEntity(GetMainDb(), params["tableName"])
	if !bl {
		return bl, msg, da
	}

	entity := da.(*dbinfo.TableInfo)

	return GetService(entity.DbName, entity.Name).Add(ctx, entity, params)
}

// Adds 批量添加数据
func (c *BaseSystemController) Adds(ctx *gin.Context) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	bl, msg, da := sqlfactory.AnalysisEntity(GetMainDb(), params["tableName"])
	if !bl {
		return bl, msg, da
	}

	entity := da.(*dbinfo.TableInfo)

	data, ok := params["data"].([]map[string]interface{})
	if !ok {
		return false, "从请求参数解析数据发生异常", 9002
	}

	return GetService(entity.DbName, entity.Name).Adds(ctx, entity, data)
}

// EditData 更新数据
func (c *BaseSystemController) Edit(ctx *gin.Context) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	bl, msg, data := sqlfactory.AnalysisEntity(GetMainDb(), params["tableName"])
	if !bl {
		return bl, msg, data
	}

	entity := data.(*dbinfo.TableInfo)

	return GetService(entity.DbName, entity.Name).Edit(ctx, entity, params)
}

// Edits 批量更新数据
func (c *BaseSystemController) Edits(ctx *gin.Context) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	bl, msg, data := sqlfactory.AnalysisEntity(GetMainDb(), params["tableName"])
	if !bl {
		return bl, msg, data
	}

	entity := data.(*dbinfo.TableInfo)

	updates, ok := params["updates"].([]struct {
		Conditions []dbinfo.QueryCondition
		Data       map[string]interface{}
	})
	if !ok {
		return false, "从请求参数解析数据发生异常", 9002
	}

	return GetService(entity.DbName, entity.Name).Edits(ctx, entity, updates)
}

// Del 删除数据
func (c *BaseSystemController) Del(ctx *gin.Context) (bool, string, interface{}) {
	params := ginutil.GetParams(ctx) // 获取请求参数

	bl, msg, data := sqlfactory.AnalysisEntity(GetMainDb(), params["tableName"])
	if !bl {
		return bl, msg, data
	}

	entity := data.(*dbinfo.TableInfo)

	return GetService(entity.DbName, entity.Name).Del(ctx, entity, params)
}

// FindTree 查询树形结构数据
func (c *BaseSystemController) FindTree(ctx *gin.Context) (bool, string, interface{}) {
	tableName := ginutil.GetParam(ctx, "tableName", "").(string)

	bl, msg, data := sqlfactory.AnalysisEntity(GetMainDb(), tableName)
	if !bl {
		return bl, msg, data
	}

	entity := data.(*dbinfo.TableInfo)

	groupColumn := ginutil.GetParam(ctx, "groupColumn", "").(string)
	groupName := ginutil.GetParam(ctx, "groupName", "").(string)

	return GetService(entity.DbName, entity.Name).FindTree(ctx, entity, groupColumn, groupName)
}

// ClearCache 清理指定用户的缓存
func (c *BaseSystemController) ClearCache(ctx *gin.Context) (bool, string, interface{}) {
	tableName := ginutil.GetParam(ctx, "tableName", "").(string)

	bl, msg, data := sqlfactory.AnalysisEntity(GetMainDb(), tableName)
	if !bl {
		return bl, msg, data
	}

	entity := data.(*dbinfo.TableInfo)

	user := ginutil.GetParam(ctx, "user", "").(string)           //取请求参数中的用户名
	cacheName := ginutil.GetParam(ctx, "cacheName", "").(string) //取请求参数中的缓存名

	return GetService(entity.DbName, entity.Name).ClearCache(ctx, entity, user, cacheName)
}

// FindGroup 查询组结构数据
func (c *BaseSystemController) FindGroup(ctx *gin.Context) (bool, string, interface{}) {
	tableName := ginutil.GetParam(ctx, "tableName", "").(string)

	bl, msg, data := sqlfactory.AnalysisEntity(GetMainDb(), tableName)
	if !bl {
		return bl, msg, data
	}

	entity := data.(*dbinfo.TableInfo)

	groupColumn := ginutil.GetParam(ctx, "groupColumn", "english").(string) //分组名(树节点)所在字段名
	groupName := ginutil.GetParam(ctx, "groupName", "").(string)            //分组名(树节点)

	return GetService(entity.DbName, entity.Name).FindByGroup(ctx, entity, groupColumn, groupName)
}
